package com.hyt.it.ogt.log.interceptor.interceptor;

import com.hyt.core.util.UUIDUtils;
import com.hyt.it.ogt.log.interceptor.constants.LogCommonConstants;
import org.slf4j.MDC;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * @author 朱振宇
 * @since 2023-02-14
 */
public abstract class TraceContext {
    private static final ThreadLocal<Long> timeThreadLocal = new ThreadLocal<>();

    /**
     * 开始计时
     *
     */
    public static void start() {
        long startTime = System.nanoTime();
        timeThreadLocal.set(startTime);
    }

    /**
     * 获取接口耗时
     *
     */
    public static long stopAndGet() {
        long endTime = System.nanoTime();
        Long startTime = timeThreadLocal.get();
        if (startTime == null) {
            throw new IllegalArgumentException("必须先调用start方法");
        }
        //移除
        timeThreadLocal.remove();
        long costTime = endTime - startTime;
        return TimeUnit.MILLISECONDS.convert(costTime, TimeUnit.NANOSECONDS);
    }

    //---------trace相关
    public static String getTraceId() {
        return MDC.get(LogCommonConstants.SLF4J_TRACE_ID);
    }

    public static String getSpanId() {
        return MDC.get(LogCommonConstants.SLF4j_SPAN_ID);
    }

    public static String getRequestUri() {
        return MDC.get(LogCommonConstants.SLF4j_REQUEST_URI);
    }

    public static String getMethodName() {
        return MDC.get(LogCommonConstants.SLF4j_METHOD_NAME);
    }

    public static String getRequestBody() {
        return MDC.get(LogCommonConstants.SLF4j_REQUEST_BODY);
    }

    /**
     * 获取traceId，如果不存在则生成一个
     *
     */
    public static String computeTraceId() {
        String traceId = getTraceId();
        if (StringUtils.isEmpty(traceId)) {
            traceId = UUIDUtils.randomUUID();
        }
        return traceId;
    }

    public static void putTraceId(String traceId) {
        MDC.put(LogCommonConstants.SLF4J_TRACE_ID, traceId);
    }

    public static void putSpanId(String spanId) {
        MDC.put(LogCommonConstants.SLF4j_SPAN_ID, spanId);
    }

    public static void putRequestUri(String requestUri) {
        MDC.put(LogCommonConstants.SLF4j_REQUEST_URI, requestUri);
    }

    public static void putMethodName(String methodName) {
        MDC.put(LogCommonConstants.SLF4j_METHOD_NAME, methodName);
    }

    public static void putRequestBody(String requestBody) {
        MDC.put(LogCommonConstants.SLF4j_REQUEST_BODY, requestBody);
    }

    public static void removeTraceId() {
        MDC.remove(LogCommonConstants.SLF4J_TRACE_ID);
    }

    public static void removeAll() {
        removeRequestUri();
        removeMethodName();
        removeRequestBody();
        removeTraceId();
        removeSpanId();
    }

    public static void removeSpanId() {
        MDC.remove(LogCommonConstants.SLF4j_SPAN_ID);
    }

    public static void removeRequestUri() {
        MDC.remove(LogCommonConstants.SLF4j_REQUEST_URI);
    }

    public static void removeMethodName() {
        MDC.remove(LogCommonConstants.SLF4j_METHOD_NAME);
    }

    public static void removeRequestBody() {
        MDC.remove(LogCommonConstants.SLF4j_REQUEST_BODY);
    }

    public static String genSpanId(String spanId) {
        if (StringUtils.isEmpty(spanId)) {
            return LogCommonConstants.ROOT_SPAN_ID;
        }
        return spanId + ".1";
    }

    public static String rootSpanId() {
        return LogCommonConstants.ROOT_SPAN_ID;
    }
}